#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <netdb.h> 
#include <unistd.h>
#include <pthread.h>
#include <ncurses.h>

#include <network.h>
#include <MyInterface.h>

/*									*/
struct hostent *server;
struct sockaddr_in serveraddr;
WINDOW *board;
int port = 2012;
int sockfd = 0;
int myid = -1;
int reconnect = 0;
/*									*/

void exitNow(char *msg){ // Выводит сообщение и выходит.
	if (msg != NULL){
		printf("%s\n", msg);
	}
	if (sockfd > 0){
		close(sockfd);
	}
	exit(0);
}

void scanArgs(int argc, char *argv[]){ // Сканирование аргуентов
	struct option long_options[] = {
		 {"server", required_argument, NULL, 's'},
		 {"port", required_argument, NULL, 'p'},
		 {0, 0, 0, 0} 
	     };
	char arg; 

	while ((arg = getopt_long(argc, argv, "s:p:", long_options, NULL)) != -1){
		switch (arg){
			case 's':{ 
				    server = gethostbyname(optarg); // domain -> ip
    				if (server == NULL) {
						exitNow("Ошибка. Неверное имя сервера.");
   					 }
				break;
			}
			case 'p':{
				port = atoi(optarg);
				if ((1024 > port) || (port > 65536))
					exitNow("Ошибка. Неверный порт.");
				break;
			}
			default:
				exitNow("[-s|--server IP сервера] [-p|--port Номер порта]");
		}
	}

    if (server == NULL){
		server = gethostbyname("localhost");
    }
}

void networkInitialization(){
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
        exitNow("Ошибка при создании сокета.");
	
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(port);
    bcopy((char *)server->h_addr, (char *)&serveraddr.sin_addr.s_addr, server->h_length);

    if (connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0) 
        exitNow("Ошибка при установке соединения.");
}

void manualControl(){
	printf("Включен ручной контроль отправки пакетов!\n");
	char msg[256];
	int code;
	while(sockfd > 0){
		printf("Код:");
		scanf("%d",&code);
		printf("Сообщение:");
		scanf("%s",msg);
		sending(sockfd, code, msg);
	}
}

void *network(){
	char *receiveMessage;
	int code;

reconnect:
	if(reconnect == 1) {
		char buffer[4];
		sprintf(buffer, "%d", myid);
		sending(sockfd, ASWID, buffer);
	}
	while((sockfd > 0) && ((recv(sockfd, &code, sizeof(int), MSG_PEEK)) > 0)){
		receiveMessage = receiving(sockfd);
		switch(code){
			case MESSAGE:{
				print_message(receiveMessage);
				break;
			}
			case YOURID:{
				myid = atoi(receiveMessage);
				break;
			}
			case STARTUSERLIST:{
				cleanUserList();
				break;
			}
			case USERLIST:{
				refresh_client_list(receiveMessage);
				refresh_client_list("\n");
				break;
			}
			default:{
				break;
			}
		}
	}
		sleep(1);
		port++;
		networkInitialization();
		reconnect = 1;
		goto reconnect;
	exitNow(NULL);
	return NULL;
}

int main(int argc, char *argv[])
{
	scanArgs(argc, argv);
	networkInitialization();
	pthread_t netThread;
	pthread_create(&netThread, NULL, network, NULL);
//	manualControl();
	main_menu();
	close(sockfd);
	return 0;
}

